#include <rtthread.h>
#include <rtdevice.h>
#include <wlan_mgnt.h>
#include "wifi_config.h"
#include <stdlib.h>
#include <onenet.h>
#include <string.h>
#include <ap3216c.h>
#include <easyflash.h>
#include <drv_gpio.h>
#include <drv_lcd.h>
#include "aht10.h"

#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

#define I2C_BUS_NAME "i2c1"
const char *i2c_bus_name1 = "i2c2";
#define LED_PIN PIN_LED_R


ap3216c_device_t dev;
aht10_device_t dev1;

int main(void)
{
    int res;
    rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT);
    /* 设置电机控制引脚为输出模式 */
    rt_pin_mode(PIN_MOTOR_A, PIN_MODE_OUTPUT);
    rt_pin_mode(PIN_MOTOR_B, PIN_MODE_OUTPUT);

    /* 设置蜂鸣器引脚为输出模式 */
    rt_pin_mode(PIN_BEEP, PIN_MODE_OUTPUT);
    /* 清屏 */
    lcd_clear(WHITE);
    
    /* 设置背景色和前景色 */
    lcd_set_color(WHITE, BLACK);
    
    /* 初始化 ap3216c */
    dev = ap3216c_init(I2C_BUS_NAME);
    if (dev == RT_NULL)
    {
        LOG_E(" The ap3216c sensor initializes failure");
        return 0;
    }
    /* 初始化 aht10 */
    dev1 = aht10_init(i2c_bus_name1);
    if (dev1 == RT_NULL)
    {
        LOG_E(" The aht10 sensor initializes failure");
        return 0;
    }
    /* 初始化 wlan 自动连接 */
    wlan_autoconnect_init();
    /* 使能 wlan 自动连接 */
    rt_wlan_config_autoreconnect(RT_TRUE);

    res = onenet_mqtt_init();
    if(res)
    {
        LOG_E(" onenet mqtt init failure");
        return 0;
    }

    return 0;
}

static void onenet_upload_entry(void *parameter)
{
    int light = 0;
    float humidity, temperature;

    /* 上传数据至onenet */
    while(1)
    {
        light = (int)ap3216c_read_ambient_light(dev);
        /* 读取湿度 */
        humidity = aht10_read_humidity(dev1);
        /* 读取温度 */
        temperature = aht10_read_temperature(dev1);
        if (onenet_mqtt_upload_digit("temperature", temperature) < 0)
        {
            LOG_E("upload has an error, stop uploading");
            break;
        }
        else
        {
            LOG_D("buffer : {\"temperature\":%d.%d}", (int)temperature, (int)(temperature * 10) % 10);
            lcd_show_string(10, 16+30, 24, "temperature: %d.%d",(int)temperature, (int)(temperature * 10) % 10);
        }
        rt_thread_mdelay(500);
        
        if (onenet_mqtt_upload_digit("light", light) < 0)
        {
            LOG_E("upload has an error, stop uploading");
            break;
        }
        else
        {
            LOG_D("buffer : {\"light\":%d}", light);
            lcd_show_string(10, 16, 24, "light: %3d",(int)light);
        }
        rt_thread_mdelay(500);
        
        if (onenet_mqtt_upload_digit("humidity", humidity) < 0)
        {
            LOG_E("upload has an error, stop uploading");
            break;
        }
        else
        {
            LOG_D("buffer : {\"humidity\":%d.%d}", (int)humidity, (int)(humidity * 10) % 10);
            lcd_show_string(10, 16+30+30, 24, "humidity: %d.%d",(int)humidity, (int)(humidity * 10) % 10);
        }
        
        if(light>10)
        {
            rt_pin_write(LED_PIN,PIN_HIGH);
        }
        else
        {
            rt_pin_write(LED_PIN,PIN_LOW);
        }
        if(temperature>30||humidity>60)
        {
            rt_pin_write(PIN_BEEP, PIN_HIGH);
            rt_pin_write(PIN_MOTOR_A, PIN_LOW);
            rt_pin_write(PIN_MOTOR_B, PIN_HIGH);
        }
        else
        {
            rt_pin_write(PIN_BEEP, PIN_LOW);
            rt_pin_write(PIN_MOTOR_A, PIN_LOW);
            rt_pin_write(PIN_MOTOR_B, PIN_LOW);
            
        }
        
        rt_thread_mdelay(2 * 1000);
    }
}

void onenet_upload_cycle(void)
{
    rt_thread_t tid;

    /* 创建线程 */
    tid = rt_thread_create("onenet_send",
                           onenet_upload_entry,
                           RT_NULL,
                           2 * 1024,
                           1,
                           5);
    if (tid)
    {
        rt_thread_startup(tid);
    }
}
MSH_CMD_EXPORT(onenet_upload_cycle, upload data to onenet);


//onenet设备自动注册接口 移植
rt_err_t onenet_port_save_device_info(char *dev_id, char *api_key)
{
    EfErrCode err = EF_NO_ERR;

    /* 保存设备 ID */
    err = ef_set_and_save_env("dev_id", dev_id);
    if (err != EF_NO_ERR)
    {
        LOG_E("save device info(dev_id : %s) failed!", dev_id);
        return -RT_ERROR;
    }

    /* 保存设备 api_key */
    err = ef_set_and_save_env("api_key", api_key);
    if (err != EF_NO_ERR)
    {
        LOG_E("save device info(api_key : %s) failed!", api_key);
        return -RT_ERROR;
    }

    /* 保存环境变量：已经注册 */
    err = ef_set_and_save_env("already_register", "1");
    if (err != EF_NO_ERR)
    {
        LOG_E("save already_register failed!");
        return -RT_ERROR;
    }

    return RT_EOK;
}

rt_err_t onenet_port_get_register_info(char *dev_name, char *auth_info)
{
    rt_uint32_t cpuid[2] = {0};
    EfErrCode err = EF_NO_ERR;

    /* 获取 stm32 uid */
    cpuid[0] = *(volatile rt_uint32_t *)(0x1FFF7590);
    cpuid[1] = *(volatile rt_uint32_t *)(0x1FFF7590 + 4);

    /* 设置设备名和鉴权信息 */
    rt_snprintf(dev_name, ONENET_INFO_AUTH_LEN, "%d%d", cpuid[0], cpuid[1]);
    rt_snprintf(auth_info, ONENET_INFO_AUTH_LEN, "%d%d", cpuid[0], cpuid[1]);

    /* 保存设备鉴权信息 */
    err = ef_set_and_save_env("auth_info", auth_info);
    if (err != EF_NO_ERR)
    {
        LOG_E("save auth_info failed!");
        return -RT_ERROR;
    }

    return RT_EOK;
}

rt_err_t onenet_port_get_device_info(char *dev_id, char *api_key, char *auth_info)
{
    char *info = RT_NULL;

    /* 获取设备 ID */
    info = ef_get_env("dev_id");
    if (info == RT_NULL)
    {
        LOG_E("read dev_id failed!");
        return -RT_ERROR;
    }
    else
    {
        rt_snprintf(dev_id, ONENET_INFO_AUTH_LEN, "%s", info);
    }

    /* 获取 api_key */
    info = ef_get_env("api_key");
    if (info == RT_NULL)
    {
        LOG_E("read api_key failed!");
        return -RT_ERROR;
    }
    else
    {
        rt_snprintf(api_key, ONENET_INFO_AUTH_LEN, "%s", info);
    }

    /* 获取设备鉴权信息 */
    info = ef_get_env("auth_info");
    if (info == RT_NULL)
    {
        LOG_E("read auth_info failed!");
        return -RT_ERROR;
    }
    else
    {
        rt_snprintf(auth_info, ONENET_INFO_AUTH_LEN, "%s", info);
    }

    return RT_EOK;
}

rt_bool_t onenet_port_is_registed(void)
{
    char *already_register = RT_NULL;

    /* 检查设备是否已经注册 */
    already_register = ef_get_env("already_register");
    if (already_register == RT_NULL)
    {
        return RT_FALSE;
    }

    return already_register[0] == '1' ? RT_TRUE : RT_FALSE;
}


